package com.ruoyi.exam.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.exam.domain.ExamBankQuestion;
import com.ruoyi.exam.domain.ExamQuestion;
import com.ruoyi.exam.domain.ExamUserPracticeRecord;
import com.ruoyi.exam.domain.ExamUserBankProgress;
import com.ruoyi.exam.vo.ExamQuestionVo;
import com.ruoyi.exam.vo.ExamQuestionDetailVo;
import com.ruoyi.exam.vo.ExamQuestionFavoriteVo;
import com.ruoyi.exam.vo.ExamQuestionOptionVo;
import com.ruoyi.exam.vo.ExamQuestionAnswerVo;
import com.ruoyi.exam.vo.ExamUserBankProgressVo;
import com.ruoyi.exam.vo.SubmitAnswerVo;
import com.ruoyi.exam.vo.SubmitAnswerResultVo;
import com.ruoyi.exam.vo.ExamQuestionWithSortVo;
import com.ruoyi.exam.vo.ExamBankQuestionAnswerInfoVo;
import com.ruoyi.exam.vo.ExamErrorQuestionVo;
import com.ruoyi.exam.vo.ExamUserPracticeRecordVo;
import com.ruoyi.exam.mapper.ExamBankQuestionMapper;
import com.ruoyi.exam.mapper.ExamQuestionMapper;
import com.ruoyi.exam.service.IExamBankQuestionService;
import com.ruoyi.exam.service.IExamErrorQuestionService;
import com.ruoyi.exam.service.IExamQuestionService;
import com.ruoyi.exam.service.IExamQuestionOptionService;
import com.ruoyi.exam.service.IExamQuestionAnswerService;
import com.ruoyi.exam.service.IExamQuestionFavoriteService;
import com.ruoyi.exam.service.IExamUserPracticeRecordService;
import com.ruoyi.exam.service.IExamUserBankProgressService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 题目Service业务层处理
 *
 * @author Tellsea
 * @date 2025-05-30
 */
@Service
public class ExamQuestionServiceImpl extends ServiceImpl<ExamQuestionMapper, ExamQuestion> implements IExamQuestionService {

    @Autowired
    private IExamBankQuestionService examBankQuestionService;

    @Autowired
    private ExamBankQuestionMapper examBankQuestionMapper;

    @Autowired
    private IExamQuestionOptionService examQuestionOptionService;

    @Autowired
    private IExamQuestionAnswerService examQuestionAnswerService;

    @Autowired
    private IExamUserPracticeRecordService examUserPracticeRecordService;

    @Autowired
    private IExamUserBankProgressService examUserBankProgressService;

    @Autowired
    private IExamQuestionFavoriteService examQuestionFavoriteService;

    @Autowired
    private IExamErrorQuestionService examErrorQuestionService;

    @Override
    public TableDataInfo<ExamQuestionVo> queryList(ExamQuestionVo entity) {
        return PageUtils.buildDataInfo(this.baseMapper.queryList(PageUtils.buildPage(), entity));
    }

    @Override
    public List<ExamQuestionVo> queryAll(ExamQuestionVo entity) {
        return this.baseMapper.queryList(entity);
    }

    @Override
    public ExamQuestionVo queryById(Long questionId) {
        return this.baseMapper.queryById(questionId);
    }

    @Override
    public ExamQuestionDetailVo queryDetailById(Long questionId,Long userId) {
        // 查询题目基本信息
        ExamQuestionVo questionVo = this.baseMapper.queryById(questionId);
        if (questionVo == null) {
            return null;
        }

        // 创建详细信息VO对象
        ExamQuestionDetailVo detailVo = new ExamQuestionDetailVo();
        BeanUtils.copyProperties(questionVo, detailVo);

        // 查询题目选项
        ExamQuestionOptionVo optionQuery = new ExamQuestionOptionVo();
        optionQuery.setQuestionId(questionId);
        List<ExamQuestionOptionVo> options = examQuestionOptionService.queryAll(optionQuery);
        detailVo.setOptions(options);

        // 查询题目答案
        ExamQuestionAnswerVo answerQuery = new ExamQuestionAnswerVo();
        answerQuery.setQuestionId(questionId);
        List<ExamQuestionAnswerVo> answers = examQuestionAnswerService.queryAll(answerQuery);
        detailVo.setAnswers(answers);


        // 设置题库ID列表（如果questionVo已包含则直接使用）
        if (questionVo instanceof ExamQuestionVo && ((ExamQuestionVo) questionVo).getQuestionBankIds() != null) {
            detailVo.setQuestionBankIds(((ExamQuestionVo) questionVo).getQuestionBankIds());
        }

        // 查询当前用户是否已收藏该题目
        if (userId != null) {
            ExamQuestionFavoriteVo favoriteQuery = new ExamQuestionFavoriteVo();
            favoriteQuery.setUserId(userId);
            favoriteQuery.setQuestionId(questionId);
            List<ExamQuestionFavoriteVo> favorites = examQuestionFavoriteService.queryAll(favoriteQuery);
            detailVo.setIsFavorite(favorites != null && !favorites.isEmpty());

            // 查询当前用户对该题目的作答记录
            ExamUserPracticeRecordVo recordQuery = new ExamUserPracticeRecordVo();
            recordQuery.setUserId(userId);
            recordQuery.setQuestionId(questionId);
            recordQuery.setStatus("1"); // 只查询正常状态的记录
            List<ExamUserPracticeRecordVo> records = examUserPracticeRecordService.queryAll(recordQuery);
            
            if (records != null && !records.isEmpty()) {
                // 取最新的一条记录
                ExamUserPracticeRecordVo latestRecord = records.get(0);
                detailVo.setHasAnswered(true);
                detailVo.setIsCorrect("1".equals(latestRecord.getIsCorrect()));
                detailVo.setSelectedOptions(latestRecord.getSelectedOptions());
            } else {
                detailVo.setHasAnswered(false);
                detailVo.setIsCorrect(null);
                detailVo.setSelectedOptions(null);
            }
        } else {
            detailVo.setIsFavorite(false);
            detailVo.setHasAnswered(false);
            detailVo.setIsCorrect(null);
            detailVo.setSelectedOptions(null);
        }

        return detailVo;
    }

    @Override
    public ExamBankQuestionAnswerInfoVo queryRecordInfo(Long questionId, Long bankId) {
        // 获取当前用户ID
        Long userId = SecurityUtils.getUserId();
        
        // 查询题目详细信息
        ExamQuestionDetailVo questionDetail = queryDetailById(questionId, userId);
        if (questionDetail == null) {
            throw new RuntimeException("题目不存在");
        }

        // 创建返回对象
        ExamBankQuestionAnswerInfoVo answerInfo = new ExamBankQuestionAnswerInfoVo();
        
        // 查询题目在题库中的序号
        List<ExamQuestionWithSortVo> allQuestions = examBankQuestionService.getQuestionsByBankId(userId, bankId);
        for (ExamQuestionWithSortVo q : allQuestions) {
            if (q.getQuestionId().equals(questionId)) {
                answerInfo.setSortOrder(q.getSortOrder());
                break;
            }
        }

        // 查询用户的答题记录
        ExamUserPracticeRecordVo recordQuery = new ExamUserPracticeRecordVo();
        recordQuery.setUserId(userId);
        recordQuery.setBankId(bankId);
        recordQuery.setQuestionId(questionId);
        List<ExamUserPracticeRecordVo> records = examUserPracticeRecordService.queryAll(recordQuery);
        
        if (records != null && !records.isEmpty()) {
            // 取最新的一条记录
            ExamUserPracticeRecordVo latestRecord = records.get(0);
            answerInfo.setUserRecord(latestRecord);
            answerInfo.setHasAnswered(true);
            answerInfo.setIsCorrect("1".equals(latestRecord.getIsCorrect()));
            answerInfo.setSelectedOptions(latestRecord.getSelectedOptions());
            answerInfo.setAnswerTime(latestRecord.getAnswerTime());
            answerInfo.setAnswerDate(latestRecord.getCreateTime());
        } else {
            answerInfo.setHasAnswered(false);
            answerInfo.setIsCorrect(false);
        }

        //查询当前题目是否已经收藏
        ExamQuestionFavoriteVo query = new ExamQuestionFavoriteVo();
        query.setUserId(userId);
        query.setQuestionId(questionId);
        List<ExamQuestionFavoriteVo> list = examQuestionFavoriteService.queryAll(query);
        if (list.size() > 0) {
            answerInfo.setIsFavorite(true);
        }else{
            answerInfo.setIsFavorite(false);
        }

        return answerInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SubmitAnswerResultVo submitAnswer(SubmitAnswerVo submitAnswerVo, Long userId) {  
        // 1. 获取题目详细信息
        ExamQuestionDetailVo questionDetail = queryDetailById(submitAnswerVo.getQuestionId(), userId);
        if (questionDetail == null) {
            throw new RuntimeException("题目不存在");
        }

        // 2. 判断答案是否正确并计算得分
        SubmitAnswerResultVo result = new SubmitAnswerResultVo();
        boolean isCorrect = checkAnswer(questionDetail, submitAnswerVo);
        if(!isCorrect){
            //错误，加入错题记录
            ExamErrorQuestionVo errorQuestion = new ExamErrorQuestionVo();
            errorQuestion.setUserId(userId);
            errorQuestion.setBankId(submitAnswerVo.getBankId());
            errorQuestion.setQuestionId(submitAnswerVo.getQuestionId());
            examErrorQuestionService.addErrorQuestion(errorQuestion);
        }
        result.setIsCorrect(isCorrect);
        result.setSelectedOptions(submitAnswerVo.getUserAnswer());
        
        // 获取正确选项
        List<String> correctOptions = questionDetail.getOptions().stream()
                .filter(option -> "1".equals(option.getIsCorrect()))
                .map(ExamQuestionOptionVo::getOptionLabel)
                .collect(Collectors.toList());
        result.setCorrectOptions(correctOptions);
        result.setQuestionAnalysis(questionDetail.getQuestionAnalysis());

        // 计算得分
        BigDecimal score = BigDecimal.ZERO;
        if (isCorrect && questionDetail.getScore() != null) {
            score = questionDetail.getScore();
        }
        result.setScore(score);

        // 3. 保存答题记录
        ExamUserPracticeRecord record = new ExamUserPracticeRecord();
        record.setUserId(userId);
        record.setBankId(submitAnswerVo.getBankId());
        record.setQuestionId(submitAnswerVo.getQuestionId());
        record.setAnswerContent(submitAnswerVo.getAnswerContent());
        record.setSelectedOptions(submitAnswerVo.getUserAnswer());
        record.setIsCorrect(result.getIsCorrect() ? "1" : "0");
        record.setScore(score);
        record.setAnswerTime(submitAnswerVo.getAnswerTime());
        record.setPracticeMode(submitAnswerVo.getPracticeMode());
        record.setStatus("1");
        record.setCreateBy(SecurityUtils.getUsername());
        record.setCreateTime(new Date());
        
        examUserPracticeRecordService.save(record);
        result.setRecordId(record.getRecordId());

        // 4. 更新用户题库进度
        ExamUserBankProgressVo progress = updateUserProgress(userId, submitAnswerVo.getBankId(), 
                submitAnswerVo.getQuestionId(), isCorrect, submitAnswerVo.getAnswerTime());
        result.setProgress(progress);

        // 5. 获取下一题信息
        SubmitAnswerResultVo.NextQuestionInfo nextQuestion = new SubmitAnswerResultVo.NextQuestionInfo();
        nextQuestion.setQuestionId(progress.getCurrentQuestionId());
        result.setNextQuestion(nextQuestion);

        return result;
    }

    /**
     * 检查答案是否正确
     */
    private boolean checkAnswer(ExamQuestionDetailVo questionDetail, SubmitAnswerVo submitAnswerVo) {
        String questionType = questionDetail.getQuestionType();
        
        // 获取正确选项
        List<String> correctOptions = questionDetail.getOptions().stream()
                .filter(option -> "1".equals(option.getIsCorrect()))
                .map(ExamQuestionOptionVo::getOptionLabel)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(correctOptions)) {
            return false;
        }

        // 客观题判断
        if ("1".equals(questionType) || "2".equals(questionType) || "3".equals(questionType)) {
            if (!StringUtils.hasText(submitAnswerVo.getUserAnswer())) {
                return false;
            }
            
            List<String> userOptions = Arrays.asList(submitAnswerVo.getUserAnswer().split(","));
            return userOptions.size() == correctOptions.size() && 
                   userOptions.containsAll(correctOptions);
        }
        
        // 主观题暂时返回true，实际需要人工判分
        return true;
    }

    /**
     * 更新用户题库进度
     */
    private ExamUserBankProgressVo updateUserProgress(Long userId, Long bankId, Long questionId, 
                                                     boolean isCorrect, Long answerTime) {
        // 查询当前进度
        ExamUserBankProgressVo progress = examUserBankProgressService.getByUserIdAndBankId(userId, bankId);
        
        if (progress == null) {
            // 第一次做题，创建进度记录
            progress = createInitialProgress(userId, bankId);
        }
        

        // 更新进度信息
        progress.setCompletedQuestions(progress.getCompletedQuestions() + 1);
        if (isCorrect) {
            progress.setCorrectQuestions(progress.getCorrectQuestions() + 1);
        }
        
        // 更新当前题目和序号
        List<Long> questionIds = examBankQuestionService.getQuestionIdsByBankId(bankId);
        Long nextQuestionId = getNextQuestionId(questionId, questionIds);
        if (nextQuestionId != null ) {
            // 获取下一题
            progress.setCurrentQuestionId(nextQuestionId);
        }

        // 计算完成百分比
        if (progress.getTotalQuestions() > 0) {
            BigDecimal percent = new BigDecimal(progress.getCompletedQuestions())
                    .divide(new BigDecimal(progress.getTotalQuestions()), 4, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal(100));
            progress.setProgressPercent(percent);
        }

        // 计算正确率
        if (progress.getCompletedQuestions() > 0) {
            BigDecimal accuracy = new BigDecimal(progress.getCorrectQuestions())
                    .divide(new BigDecimal(progress.getCompletedQuestions()), 4, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal(100));
            progress.setAccuracyRate(accuracy);
        }

        // 更新练习时间
        progress.setLastPracticeTime(new Date());
        if (answerTime != null) {
            progress.setTotalPracticeTime(progress.getTotalPracticeTime() + answerTime);
        }

        // 检查是否完成
        if (progress.getCompletedQuestions().equals(progress.getTotalQuestions())) {
            progress.setIsCompleted("1");
        }

        // 保存进度
        ExamUserBankProgress entity = new ExamUserBankProgress();
        BeanUtils.copyProperties(progress, entity);
        entity.setUpdateBy(SecurityUtils.getUsername());
        entity.setUpdateTime(new Date());
        examUserBankProgressService.updateById(entity);

        return progress;
    }

    /**
     * 创建初始进度记录
     */
    private ExamUserBankProgressVo createInitialProgress(Long userId, Long bankId) {
        // 获取题库总题数和第一题
        List<Long> questionIds = examBankQuestionService.getQuestionIdsByBankId(bankId);
        ExamUserBankProgress progress = new ExamUserBankProgress();
        progress.setUserId(userId);
        progress.setBankId(bankId);
        progress.setCurrentQuestionId(questionIds.get(0));
        progress.setTotalQuestions((long) questionIds.size());
        progress.setCompletedQuestions(0L);
        progress.setCorrectQuestions(0L);
        progress.setProgressPercent(BigDecimal.ZERO);
        progress.setAccuracyRate(BigDecimal.ZERO);
        progress.setTotalPracticeTime(0L);
        progress.setIsCompleted("0");
        progress.setCreateBy(SecurityUtils.getUsername());
        progress.setCreateTime(new Date());

        examUserBankProgressService.save(progress);

        ExamUserBankProgressVo progressVo = new ExamUserBankProgressVo();
        BeanUtils.copyProperties(progress, progressVo);
        return progressVo;
    }

    /**
     * 获取下一题信息
     */
    // private SubmitAnswerResultVo.NextQuestionInfo getNextQuestionInfo(Long bankId, Long currentSortOrder) {
    //     SubmitAnswerResultVo.NextQuestionInfo nextInfo = new SubmitAnswerResultVo.NextQuestionInfo();
        
    //     ExamQuestionWithSortVo nextQuestion = examBankQuestionService.getNextQuestion(bankId, currentSortOrder);
    //     if (nextQuestion != null) {
    //         nextInfo.setQuestionId(nextQuestion.getQuestionId());
    //         nextInfo.setSortOrder(nextQuestion.getSortOrder());
    //         nextInfo.setHasNext(true);
    //     } else {
    //         nextInfo.setHasNext(false);
    //     }
        
    //     return nextInfo;
    // }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateQuestionBankIds(ExamQuestionVo entity) {
        if (entity.getQuestionId() == null) {
            return;
        }
        
        // 删除题目的所有现有题库关联
        LambdaQueryWrapper<ExamBankQuestion> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(ExamBankQuestion::getQuestionId, entity.getQuestionId());
        examBankQuestionService.remove(deleteWrapper);
        
        // 如果新的题库ID列表不为空，则重新建立关联
        if (!CollectionUtils.isEmpty(entity.getQuestionBankIds())) {
            List<ExamBankQuestion> bankQuestions = new ArrayList<>();
            for (Long bankId : entity.getQuestionBankIds()) {
                ExamBankQuestion bankQuestion = new ExamBankQuestion();
                bankQuestion.setQuestionId(entity.getQuestionId());
                bankQuestion.setBankId(bankId);
                
                // 修改：获取该题库的最大排序号+1，确保新题目排在最后
                Long maxSortOrder = examBankQuestionMapper.getMaxSortOrder(bankId);
                bankQuestion.setSortOrder(maxSortOrder + 1);
                
                bankQuestions.add(bankQuestion);
                bankQuestion.setCreateBy(SecurityUtils.getUsername());
                bankQuestion.setCreateTime(DateUtils.getNowDate());
            }
            examBankQuestionService.saveBatch(bankQuestions);
        }
    }

    private Long getNextQuestionId(Long currentQuestionId, List<Long> questionIds) {
        for (int i = 0; i < questionIds.size(); i++) {
            if (questionIds.get(i).equals(currentQuestionId)) {
                // 如果是最后一题，返回null
                if (i == questionIds.size() - 1) {
                    return null;
                }
                return questionIds.get(i + 1);
            }
        }
        return null;
    }
}
